#ifndef QPARTICLES_H
#define QPARTICLES_H

#include <QGLShaderProgram>
#include <QDeclarativeItem>
#include <QtCore/QAbstractAnimation>
#include <QVarLengthArray>
#include <QPen>

#include "qparticle.h"
#include "vertexpositioncolor.h"

#define KPARTICLES 100
#define KCOLORS  256

//an animation that just gives a tick
template<class T, void (T::*method)(int)>
class TickAnimationProxy : public QAbstractAnimation
{
    public:
        TickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {}
        virtual int duration() const { return -1; }
    protected:
        virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); }

    private:
        T *m_p;
};


class QParticles : public QDeclarativeItem
{
        Q_OBJECT
        Q_PROPERTY(int particles READ particles WRITE setParticles)
        Q_PROPERTY(float particleSize READ particleSize WRITE setParticleSize)
        Q_PROPERTY(bool squareParticle READ squareParticle WRITE setSquareParticle)
    public:
        explicit QParticles(QDeclarativeItem *parent = 0);

        void tick(int time);
        void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
        Q_INVOKABLE void onActivated();

        TickAnimationProxy<QParticles, &QParticles::tick> clock;

    protected:
        bool sceneEvent(QEvent *event);
//        bool event(QEvent *event);


    public:
        void setParticles(int aNewParticlesCount);
        int particles() const;

        void setParticleSize(float aParticleSize);
        float particleSize() const;

//        void setdrawOnUI(bool aDrawOnUI);
//        bool drawOnUI() const;

        void setSquareParticle(bool aSquareParticle);
        bool squareParticle() const;

    private:
        int randInt(int low, int high) const;
        bool updateParticles(qreal deltaTime, const QRectF & boundingRect, bool dontNull);
        void applyTouchGravity(const QPointF & center);
        void generateParticles(const QRectF & boundingRect);
        void generateParticles(int aCount);
        void generateColors();

        void stopRedraw();
        void startRedraw();

        void appendParticle();

    signals:
        void particlesChanged();

    protected:
        virtual void componentComplete();
//        virtual void geometryChanged(const QRectF &newGeometry,
//                                     const QRectF &oldGeometry);

    private:
        int m_lastTickTime;
        int m_upTime;
        float m_particleSize;
        bool m_SquareParticle;

        QVector< QParticle> m_particles;
        QList<QPointF> m_touchpos;

        QVector<TVertexPositionColor> data;

        QVector< QVector4D > m_colors;

        QPen m_pen;

        int m_MatrixLoc;
        int m_VertexAtribLoc;
        int m_ColorAttribLoc;
        QGLShaderProgram * m_BaseShader;

        void paintParticles(qreal aOpacity, qreal aParticleSize);

        void InitShaders();

    private:
        // init status
        bool m_InitShader;
        bool iColorInit;
        bool iParticleInit;

    private:
        QVector3D convertColor(int aColor) const;
};

#endif // QPARTICLES_H
